#include "scene_graph_loader.h"
#include "scene_graph.h"
#include "scene_graph_manager.h"
#include "parser_list.h"

using namespace krryn::scene;
using namespace krryn::parsers;

scene_graph_loader::scene_graph_loader() : m_Root(new scene_graph()) {}

void scene_graph_loader::accept(parser_list_node *a_Node){
	if(a_Node->m_Parent == 0){
		a_Node->m_Name = "level";
	}

	validate(a_Node, "id");

	scene_graph_node_base *l_Node = scene_graph_manager::get_instance()->create(
		get(a_Node, "id")->front(),
		a_Node->m_Name
	);

	if(l_Node == 0){
		throw node_not_found(a_Node->m_Name);
	}

	if(a_Node->m_Parent == 0){
		m_Root->set_root(m_Current = l_Node);
	}else{
		m_Current->add_child(l_Node);
	}

	if(a_Node->m_Children.empty() && a_Node->m_Parent){
		m_Current = l_Node->m_Parent;
	}else{
		m_Current = l_Node;
	}
}

std::vector<std::string> *scene_graph_loader::get(
	krryn::parsers::parser_list_node *a_Node,
	const std::string &a_Property) const{

	std::map<std::string, std::vector<std::string>* >::iterator l_Index 
		= a_Node->m_Properties.find(a_Property);

	if(l_Index == a_Node->m_Properties.end())
		return 0;

	return l_Index->second;
}

void scene_graph_loader::validate(
	krryn::parsers::parser_list_node *a_Node, 
	const std::string &a_Property) const{

	std::map<std::string, std::vector<std::string>* >::iterator l_Index 
		= a_Node->m_Properties.find(a_Property);

	if(l_Index == a_Node->m_Properties.end() || (*l_Index).second->empty()){
		throw required_property_not_found(a_Node->m_Name, a_Property);
	}
}

scene_graph* scene_graph_loader::get_scene_graph(){
	return m_Root;
}
